package gui.tables;

import gui.categories.CategoryPanel;
import gui.overview.OverviewPanel;

import java.awt.*;  

import javax.swing.*;  
import javax.swing.table.*;  

import java.awt.event.*;  
import java.util.Vector;

/**
 * Spezielle JTable-Variante mit Checkboxen in der ersten (linken) Spalte und
 * der dazugehoerigen Header-Zelle. Das Markieren der Header Checkbox fuehrt zum
 * Markieren aller darunter liegenden Checkboxen. Ein weiterer Klick entfernt
 * alle Markierungen.
 * @author Dennis Wittkoetter
 */
public class JTableHeaderCheckBox //implements ActionListener
{  
	/**Spaltenbezeichner*/
	protected Object[] columnNames = {"", "String", "String"}; 
	/**Zelleninhalte*/
	protected Object[][] data = null;
	/**basierendes Tablemodel
	 * @see javax.swing.table.DefaultTableModel*/
	protected DefaultTableModel dtm;
	/**basierende JTable
	 * @see javax.swing.JTable*/
	protected JTable table;  
  
	/**
	 * ItemListener zum automatischen Markieren / Demarkieren aller Checkboxen
	 * der Checkbox-Spalte der Kategorie-Tabelle
	 * @see java.awt.event.ItemListener
	 */
	protected class MyItemListenerCategory implements ItemListener {  
		@Override public void itemStateChanged(ItemEvent e) {  
			Object source = e.getSource();  
			if (source instanceof AbstractButton == false) return;  
			boolean checked = e.getStateChange() == ItemEvent.SELECTED;  
			for(int x = 0, y = table.getRowCount(); x < y; x++) {
				table.setValueAt(new Boolean(checked),x,0);  
				//System.out.println(table.getValueAt(x, 0));
			}  
			if(checked){
				CategoryPanel.getBtnDeleteChoice().setEnabled(true);
				CategoryTable.setBool(true);
			}else{
				CategoryPanel.getBtnDeleteChoice().setEnabled(false);
				CategoryTable.setBool(false);
			}
		}  
	}
	/**
	 * ItemListener zum automatischen Markieren / Demarkieren aller Checkboxen
	 * der Checkbox-Spalte der Uebersichtstabelle
	 * @see java.awt.event.ItemListener
	 */
	protected class MyItemListenerOverview implements ItemListener {  
		@Override public void itemStateChanged(ItemEvent e) {  
			Object source = e.getSource();  
			if (source instanceof AbstractButton == false) return;  
			boolean checked = e.getStateChange() == ItemEvent.SELECTED;  
			for(int x = 0, y = table.getRowCount(); x < y; x++) {
				table.setValueAt(new Boolean(checked),x,0);
			}  
			if(checked){
				OverviewPanel.getbtn().setEnabled(true);
				OverviewTable.setHeaderCheckBox(true);
			}else{
				OverviewPanel.getbtn().setEnabled(false);
				OverviewTable.setHeaderCheckBox(false);
			}
		}  
	}
	
	/**
	 * Default-Konstruktor
	 * Konstruiert eine Tabelle mit Standard-Spaltenbezeichnern
	 */
	public JTableHeaderCheckBox() {
		dtm = new DefaultTableModel(data,columnNames);  
	    table = new JTable(dtm);
	}
	
	/**
	 * Konstruiert eine Tabelle mit angegebenen Spaltenbezeichnern
	 * @param colNames	Spaltenbezeichner
	 */
	public JTableHeaderCheckBox(Object[] colNames) {
		columnNames = new Object[colNames.length+1];
        columnNames[0] = "";
        for (int i=0; i<colNames.length; i++) {
        	columnNames[i+1] = colNames[i];
        }
		
		dtm = new DefaultTableModel(data,columnNames);  
	    table = new JTable(dtm);  
	}
	
	/**
	 * Erstellt eine JPanel zur Implementation der Tabelle in ein GUI.
	 * Die JTableHeaderCheckBox wird zusaetzlich in eine JScrollpane gepackt.
	 * @return	JPanel mit JScrollPane und JTableHeaderCheckBox
	 */
	public JPanel buildPanel() {
		//Spalten konfigurieren:
	    //Checkbox-Spalte ist 25px breit, fix und nicht veraenderbar 
	    table.getColumnModel().getColumn(0).setPreferredWidth(25);
	    table.getColumnModel().getColumn(0).setMaxWidth(25);
	    table.getColumnModel().getColumn(0).setResizable(false);
	    
		JScrollPane sp = new JScrollPane(table);  
	    TableColumn tc = table.getColumnModel().getColumn(0);  
	    tc.setCellEditor(table.getDefaultEditor(Boolean.class));  
	    tc.setCellRenderer(table.getDefaultRenderer(Boolean.class));  
	   // tc.setHeaderRenderer(new CheckBoxHeader(new MyItemListener()));
	    
	    JPanel p = new JPanel(new BorderLayout());
	    p.add(sp);
	    return p;
	}
	
	/**
	 * Liefert die Tabelle
	 * @return	JTable der JTableHeaderCheckBox
	 */
	public JTable getTable() {
		return table;
	}
	/**
	 * Liefert das TableModel
	 * @return	DefaultTableModel der JTableHeaderCheckBox
	 */
	public DefaultTableModel getDefaultTableModel() {
		return dtm;
	}
	
	/**
	 * Zaehlt alle markierten Checkboxen der Tabelle
	 * @return	Anzahl der markierten Checkboxen
	 */
	public int getCheckedRowCount() {
		int i=0;
		for (int j=0; j<dtm.getRowCount(); j++) {
			if (dtm.getValueAt(j, 0).toString().equalsIgnoreCase("true"))
				i++;
		}
		return i;
	}

	/**
	 * Liefert den Wert der Zelle an der angegebenen Position
	 * @param row	Zeile der gesuchten Zelle
	 * @param col	Spalte der gesuchten Zelle
	 * @return		gesuchter Wert
	 */
	@SuppressWarnings("unchecked")
	public Object getValueAt(int row, int col) {
		return ((Vector<Object>)dtm.getDataVector().elementAt(row)).elementAt(col);
	}
	/*@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
	}*/
}  

/**
 * Erweiterter HeaderRenderer fuer JTableHeaderCheckBox.
 * Setzt eine Master-Checkbox in den ersten Spalten-Header.
 * @author Dennis Wittkoetter
 * @version 1.0
 * @see javax.swing.JCheckBox
 * @see javax.swing.table.TableCellRenderer
 * @see java.awt.event.MouseListener
 */
class CheckBoxHeader extends JCheckBox implements TableCellRenderer, MouseListener {
	private static final long serialVersionUID = 1L;
	protected CheckBoxHeader rendererComponent;  
	protected int column;  
	protected boolean mousePressed = false;  
	
	/**
	 * Konstruiert einen CheckBoxHeader
	 * @param itemListener	Listener fuer Header
	 */
	public CheckBoxHeader(ItemListener itemListener) {  
		rendererComponent = this;  
		rendererComponent.addItemListener(itemListener);  
	}  
  
	/**
	 * TableCellRenderer fuer CheckBoxHeader
	 * @see gui.tables.JTableHeaderCheckBox
	 */
	@Override public Component getTableCellRendererComponent(
		  JTable table, Object value, 
		  boolean isSelected, boolean hasFocus, int row, int column) {   
		
		if (table != null) {  
			JTableHeader header = table.getTableHeader();  
			if (header != null) {
		        rendererComponent.setForeground(header.getForeground());  
		        //rendererComponent.setBackground(header.getBackground());
		        rendererComponent.setFont(header.getFont());
		        header.addMouseListener(rendererComponent);  
			}
	    }
	    setColumn(column);  
	    //rendererComponent.setText("Check All");
	    setBorder(UIManager.getBorder("TableHeader.cellBorder")); 
	    return rendererComponent;  
	} 
	
	/**
	 * Setzt die Spaltenummer der aktuellen Zelle
	 * @param column	neue Spaltennummer
	 */
	protected void setColumn(int column) {  
		this.column = column;  
	}  
	
	/**
	 * Liefert die Spaltennummer der aktuellen Zelle
	 * @return	Spaltenindex
	 */
	public int getColumn() {  
		return column;  
	}  
	
	/**
	 * Markiert alle Checkboxen der ersten Spalte beim Klick auf die Zelle
	 * des Headers der ersten Spalte.
	 * @param e
	 */
	protected void handleClickEvent(MouseEvent e) {  
		if (mousePressed) {  
			mousePressed=false;  
			JTableHeader header = (JTableHeader)(e.getSource());  
			JTable tableView = header.getTable();  
			TableColumnModel columnModel = tableView.getColumnModel();  
			int viewColumn = columnModel.getColumnIndexAtX(e.getX());  
			int column = tableView.convertColumnIndexToModel(viewColumn);  
	   
			if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {  
				doClick();  
			}  
	    }  
	}
	
	/**
	 * Aktualisiert die Tabelle bei Mausklick
	 */
	@Override public void mouseClicked(MouseEvent e) {  
	    handleClickEvent(e);  
	    ((JTableHeader)e.getSource()).repaint();  
	}  
	  
	/**
	 * Registriert gedrueckte Maustatsten
	 */
	@Override public void mousePressed(MouseEvent e) {  
	    mousePressed = true;  
	}  
	
	/**
	 * Registriert losgelassene Maustasten  
	 */
	@Override public void mouseReleased(MouseEvent e) {}  
	
	/**
	 * Registriert Mausbewegungen auf das Objekt
	 */
	@Override public void mouseEntered(MouseEvent e) {} 
	
	/**
	 * Registriert Mausbewegungen beim Verlassen des Objekte
	 */
	@Override public void mouseExited(MouseEvent e) {} 
}